package com.zhangdi.dwperms.realm;

import com.zhangdi.dwcache.CacheContents;
import com.zhangdi.dwperms.bo.ShiroAccount;
import com.zhangdi.dwperms.commons.Contents;
import com.zhangdi.dwperms.dao.AccountDao;
import com.zhangdi.dwperms.dao.UserDao;
import com.zhangdi.dwperms.entity.Account;
import com.zhangdi.dwperms.entity.Role;
import com.zhangdi.dwperms.token.AuthToken;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import javax.annotation.Resource;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Created by zhangdi on 2020/07/24 16:23:28.
 */
public class BaseRealm extends AuthorizingRealm implements CustomRealm {
    @Resource
    UserDao userDao;
    @Resource
    AccountDao accountDao;

    /**
     * 初始化用户权限信息
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        ShiroAccount shiroAccount = (ShiroAccount) SecurityUtils.getSubject().getPrincipal();

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        // 获取用户角色集
        Account user = accountDao.findByUsername(shiroAccount.getUsername());
        if (user.getUser().getRoles() == null || user.getUser().getRoles().size() == 0) {
            return null;
        }
        Set<String> roleSet = user.getUser().getRoles().stream().map(Role::getName).collect(Collectors.toSet());
        simpleAuthorizationInfo.setRoles(roleSet);

        // 获取用户权限集
        Set<String> permsSet = new LinkedHashSet<>();
        user.getUser().getRoles().forEach(role -> {
            role.getMenus().forEach(menu -> {
                if (menu != null) {
                    permsSet.add(menu.getPerms());
                }
            });
        });
        simpleAuthorizationInfo.setStringPermissions(permsSet);
        return simpleAuthorizationInfo;
    }

    /**
     * 用户身份认证
     * @param authenticationToken 封装的身份信息
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        throw new UnsupportedOperationException();
    }

    /**
     * 从缓存中获取身份信息
     * @param principals
     * @return
     */
    @Override
    protected Object getAuthorizationCacheKey(PrincipalCollection principals) {
        return CacheContents.REDIS_AUTHC_USER_KEY + ((ShiroAccount) (principals.getPrimaryPrincipal())).getUsername();
    }
}
